<?php
/**
 *（Logic） AmazonAds广告授权
 */
namespace App\Logic\Amazon\AdsApi;

class Authorize
{
    private const STATE_CACHE_KEY = 'Oauth-State-';

    private const STATE_CACHE_EXPIRED = 300;

    private const STATE_RANDOM = '-State-Random-';

    const CLIENT_ID = 'amzn1.application-oa2-client.8b7c25028e0c4f21a9fa8b4c1667021e';
    const CLIENT_SECRET = 'amzn1.oa2-cs.v1.07380e33d92798756edfc876fa9614057971685618bcc2fd241f1b3184a15be7';

    const REDIRECT_URI = 'https://erp.xinqianchao.com/amazon/auth';

    /**
     * 授权地址(URL)
     * @param $regionUrl
     * @param $accountId
     * @return string
     */
    public function getOauthUrl($regionUrl,$accountId): string
    {
        $query = [];
        $query['scope'] = 'advertising::campaign_management';
        $query['response_type'] = 'code';
        $query['client_id'] = self::CLIENT_ID;
        try {
            $state = $this->_generateState($accountId);
            $query['state'] = $state;
            $query['redirect_uri'] = self::REDIRECT_URI;
        } catch (\Exception $e) {
        }
        return $regionUrl . '?' . http_build_query($query);
    }

    /**
     * 计算状态参数
     * @param $accountId
     * @return string
     * @throws \Exception
     */
    private function _generateState($accountId): string
    {
        try{
            $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!~@#$%^&*+';
            $len = strlen($str)-1;
            $random = $accountId.self::STATE_RANDOM;
            for($i = 0;$i < 50;$i++) {
                $random .= $str[mt_rand(0,$len)];
            }
            $random .= time();
            $state = encrypt($random);
            cache([self::STATE_CACHE_KEY.$accountId => $state], self::STATE_CACHE_EXPIRED);
            return $state;
        }catch (\Exception $e){
            throw new $e;
        }
    }

    /**
     * 解析状态参数
     * @param $state
     * @return array|null
     * @throws \Exception
     */
    public function parseState($state): ?array
    {
        if(!$state)return null;
        try{
            $random = decrypt($state);
            $accountId = substr($random,0,stripos($random,self::STATE_RANDOM));
            $cacheState = cache(self::STATE_CACHE_KEY.$accountId);
            return ['state' => $cacheState,'account_id' => $accountId];
        }catch (\Exception $e){
            throw new $e;
        }
    }
}
